import os
import json
import logging
from datetime import datetime
from flask import jsonify, url_for, abort, send_from_directory

# 配置日志
logger = logging.getLogger(__name__)

class HistoryModule:
    def __init__(self, upload_folder):
        self.upload_folder = upload_folder

    def save_prediction_history(self, filepath, filename, prediction_data, prediction_info, metadata=None):
        """保存预测历史记录
        Args:
            filepath: 上传文件的完整路径
            filename: 文件名
            prediction_data: 预测结果数据
            prediction_info: 预测的分类信息
            metadata: 额外的元数据
        Returns:
            bool: 是否保存成功
        """
        try:
            # 构建历史记录条目
            history_entry = {
                'timestamp': datetime.now().isoformat(),
                'prediction': prediction_data['predicted_idx'],
                'confidence': prediction_data['confidence'],
                'filename': filename,
                'main_class': prediction_info['main_class'],
                'detailed_class': prediction_info['detailed_class']
            }

            # 添加额外的元数据
            if metadata:
                history_entry.update(metadata)

            # 保存历史记录文件
            history_filename = os.path.join('user_history', f"{filename.rsplit('.', 1)[0]}_history.json")
            os.makedirs('user_history', exist_ok=True)
            with open(history_filename, 'w', encoding='utf-8') as f:
                json.dump(history_entry, f, ensure_ascii=False, indent=2)

            logger.info(f"历史记录已保存: {history_filename}")
            return True
        except Exception as e:
            logger.error(f'保存历史记录失败: {str(e)}')
            return False

    def save_prediction_with_similar(self, filepath, filename, prediction_data, prediction_info, similar_history, image_url):
        """保存预测结果和相似图片历史记录
        Args:
            filepath: 上传文件的完整路径
            filename: 文件名
            prediction_data: 预测结果数据
            prediction_info: 预测的分类信息
            similar_history: 相似图片历史记录
            image_url: 上传图片的URL
        Returns:
            dict: 预测结果及历史记录信息
        """
        try:
            # 构建元数据
            metadata = {
                'image_url': image_url,
                'similar_history': similar_history
            }

            # 保存历史记录
            if not self.save_prediction_history(filepath, filename, prediction_data, prediction_info, metadata):
                return {'error': '保存历史记录失败'}

            # 构建返回结果
            return {
                'success': True,
                'main_class': prediction_info['main_class'],
                'detailed_class': prediction_info['detailed_class'],
                'definition': prediction_info.get('definition', ''),
                'rules': prediction_info.get('rules', ''),
                'confidence': prediction_data['confidence'],
                'similar_history': similar_history,
                'image_url': image_url
            }
        except Exception as e:
            logger.error(f'保存预测结果失败: {str(e)}')
            return {'error': f'保存预测结果失败: {str(e)}'}

    def check_history_exists(self, filename):
        """检查历史记录是否存在"""
        history_filename = f"{filename.rsplit('.', 1)[0]}_history.json"
        history_path = os.path.join('user_history', history_filename)
        return os.path.exists(history_path)

    def load_history_entry(self, filename):
        """加载单个历史记录条目"""
        try:
            history_filename = f"{filename.rsplit('.', 1)[0]}_history.json"
            history_path = os.path.join('user_history', history_filename)
            
            if not os.path.exists(history_path):
                return None
                
            with open(history_path, 'r', encoding='utf-8') as f:
                return json.load(f)
        except Exception as e:
            logger.error(f'加载历史记录失败 {filename}: {str(e)}')
            return None

    def get_history(self, garbage_labels, url_for_func):
        """获取历史记录"""
        try:
            history_entries = []
            if not os.path.exists('user_history'):
                logger.warning("历史记录文件夹不存在")
                return []
                
            for filename in os.listdir('user_history'):
                if filename.endswith('_history.json'):
                    filepath = os.path.join('user_history', filename)
                    try:
                        with open(filepath, 'r', encoding='utf-8') as f:
                            entry = json.load(f)
                            logger.info(f"读取历史记录: {entry}")
                            
                            # 确保所有必要的字段都存在
                            if not all(key in entry for key in ['timestamp', 'prediction', 'confidence', 'filename']):
                                logger.warning(f"历史记录缺少必要字段: {filepath}")
                                continue
                                
                            # 处理预测结果
                            if isinstance(entry['prediction'], (int, str)):
                                predicted_idx = int(entry['prediction']) if isinstance(entry['prediction'], str) and entry['prediction'].isdigit() else entry['prediction']
                                if isinstance(predicted_idx, int):
                                    prediction_info = garbage_labels.get_prediction_info(predicted_idx)
                                    entry['detailed_class'] = prediction_info['detailed_class']
                                    entry['main_class'] = prediction_info['main_class']
                                else:
                                    logger.warning(f"无效的预测值: {entry['prediction']}")
                                    continue
                            
                            # 构造图片URL
                            image_url = url_for_func('serve_uploaded_file', filename=entry['filename'])
                            
                            # 添加到历史记录列表
                            history_entries.append({
                                'timestamp': entry['timestamp'],
                                'main_class': entry['main_class'],
                                'detailed_class': entry['detailed_class'],
                                'confidence': entry['confidence'],
                                'image_url': image_url,
                                'history_file': filename  # 添加历史记录文件名，用于删除
                            })
                    except (json.JSONDecodeError, KeyError, ValueError) as e:
                        logger.error(f"处理历史记录文件出错 {filepath}: {str(e)}")
                        continue
            
            # 按时间戳排序，最新的在前
            history_entries.sort(key=lambda x: x['timestamp'], reverse=True)
            logger.info(f"成功获取 {len(history_entries)} 条历史记录")
            return history_entries
            
        except Exception as e:
            logger.error(f"获取历史记录时出错: {str(e)}")
            return {'error': '获取历史记录失败'}

    def save_history(self, filename, prediction_data):
        """保存历史记录"""
        try:
            history_entry = {
                'timestamp': datetime.now().isoformat(),
                'prediction': prediction_data['prediction'],
                'confidence': prediction_data['confidence'],
                'filename': filename,
                'main_class': prediction_data['main_class'],
                'detailed_class': prediction_data['detailed_class']
            }
            
            history_filename = os.path.join('user_history', f"{filename.rsplit('.', 1)[0]}_history.json")
            os.makedirs('user_history', exist_ok=True)
            with open(history_filename, 'w', encoding='utf-8') as f:
                json.dump(history_entry, f, ensure_ascii=False, indent=2)
            return True
        except Exception as e:
            logger.error(f'保存历史记录失败: {str(e)}')
            return False

    def delete_history(self, filename):
        """删除历史记录及相关文件"""
        try:
            # 获取当前文件的绝对路径
            current_dir = os.path.dirname(os.path.abspath(__file__))
            
            # 处理历史记录文件名和原始图片文件名
            if filename.endswith('_history.json'):
                # 从历史记录文件名中提取原始图片文件名
                image_filename = filename.replace('_history.json', '')
            else:
                # 如果是图片文件名，构造历史记录文件名
                image_filename = filename
                filename = f"{filename.rsplit('.', 1)[0]}_history.json"
            
            # 删除 user_history 中的文件
            history_filepath = os.path.join(current_dir, 'user_history', filename)
            history_deleted = False
            if os.path.exists(history_filepath):
                try:
                    os.remove(history_filepath)
                    history_deleted = True
                    logger.info(f"成功删除历史记录文件: {history_filepath}")
                except Exception as e:
                    logger.error(f"删除历史记录文件失败 {history_filepath}: {str(e)}")
            
            # 删除 uploads 中的文件
            upload_filepath = os.path.join(current_dir, 'uploads', image_filename)
            upload_deleted = False
            if os.path.exists(upload_filepath):
                try:
                    os.remove(upload_filepath)
                    upload_deleted = True
                    logger.info(f"成功删除上传文件: {upload_filepath}")
                except Exception as e:
                    logger.error(f"删除上传文件失败 {upload_filepath}: {str(e)}")
            
            # 检查删除结果
            if history_deleted or upload_deleted:
                return {'message': '删除成功'}
            else:
                logger.warning(f"未找到要删除的文件: 历史记录={filename}, 图片={image_filename}")
                return {'error': '文件不存在', 'status_code': 404}
                
        except Exception as e:
            logger.error(f"删除操作失败 {filename}: {str(e)}")
            return {'error': '删除失败', 'status_code': 500}